home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 4
/
MacMania 4.toast
/
/
Demo's
/
Igor Demo Pro
/
3 PutContentsIn Igor Pro Folder
/
Technical Notes
/
Igor Tech Notes
/
TN006 DSP support
/
Windows & PSD TEXT
< prev
Wrap
Text File
|
1994-10-31
|
5KB
|
244 lines
Function log2(val)
variable val
return ln(val)/ln(2)
end
Function CeilPwr2(x)
variable x
return 2^(ceil(log2(x)))
end
| brings the first graph window containing the given wave to the front. If no such window is found
| then one is created.
Proc BringDestFront(w)
string w
string win
variable winIndex,didit=0
CheckDisplayed /A $w
if(V_flag) | if displayed somewhere, need to know if is graph & bring to front if so
do
win=WinName(winIndex, 1) | name of top graph window
if( cmpstr(win,"") == 0 )
break; | no more graph wndows
endif
DoWindow /F $win
CheckDisplayed $w
if(V_Flag)
didit= 1
break
endif
winIndex += 1
while(1) | exit via break
endif
if(!didit)
Display $w | if not displayed anywhere then ok to create a new window
endif
end
|******** several window functions...
| each returns the average sum square value
| this is needed for psd normalization
|********
Function ParzenOrWelch(w,isWelch)
wave w
variable isWelch
variable N=numpnts(w),tmp
variable sumsqr=0,jj=0
do
tmp= (jj-0.5*(N-1))/(0.5*(N+1))
if(isWelch)
tmp= 1 - tmp^2
else
tmp= 1-abs(tmp)
endif
sumsqr += tmp^2
w[jj] *= tmp
jj+=1
while(jj<N)
return sumsqr/N
end
Function Parzen(w)
wave w
return ParzenOrWelch(w,0)
End
Function Welch(w)
wave w
return ParzenOrWelch(w,1)
End
Function Kaiser(w,beta) | see D.F. Elliott, Handbook of Digital SIgnal Processing, Academic Press, P 68
wave w
variable beta
variable N=numpnts(w),tmp
variable IBeta= BessI(0,beta), NM1= (N-1)/2
variable sumsqr=0,jj=0
do
tmp= BessI(0,beta*sqrt(1 - ( (jj-NM1)/NM1 )^2))/IBeta
sumsqr += tmp^2
w[jj] *= tmp
jj+=1
while(jj<N)
return sumsqr/N
end
Function Hamming(w)
wave w
variable N=numpnts(w),tmp
variable omega= 2*Pi/N,mid= (N-1)/2
variable sumsqr=0,i=0
do
tmp= 0.54 + 0.46*cos(omega*(i-mid))
sumsqr += tmp^2
w[i] *= tmp
i+=1
while(i<N)
return sumsqr/N
end
Function BlackmanHarris3(w)
wave w
variable N=numpnts(w),tmp
variable omega= 2*Pi/N,mid= (N-1)/2
variable sumsqr=0,i=0
do
tmp= 0.42323 + 0.49755*cos(omega*(i-mid)) + 0.07922*cos(omega*2*(i-mid))
sumsqr += tmp^2
w[i] *= tmp
i+=1
while(i<N)
return sumsqr/N
end
Function KaiserBessel(w)
wave w
variable N=numpnts(w),tmp
variable omega= 2*Pi/N,mid= (N-1)/2
variable sumsqr=0,i=0
do
tmp= 0.40243 + 0.49804*cos(omega*(i-mid))
tmp += 0.09831*cos(omega*2*(i-mid)) + 0.00122*cos(omega*3*(i-mid))
sumsqr += tmp^2
w[i] *= tmp
i+=1
while(i<N)
return sumsqr/N
end
| Given a long data wave create a short result wave containing the Power
| Spectral Density. The name of the new wave is the name of the source + _psd
| Note: if you don't want the baggage of all the window functions, just hardwire in
| your favorite and remove the window parameter (or choose a subset)
| Also, note that a unity amplitude sine wave will give an integral peak size of
| 0.5 rather than 0.707 as one would get if a real sine wave of 1 Volt peak amplitude
| were applied across a 1 ohm resistor. Thus if you want physical meaning for
| the results you should scale by 1.414/R where R is the actual resistance.
|
| Change 941031: Divided DC component by 2
|
Macro PSD(w,seglen,window)
string w
Prompt w "data wave:",popup WaveList("*",";","")
variable seglen=1
Prompt seglen,"segment length:",popup "256;512;1024;2048;4096;8192"
variable window=2
Prompt window,"Window type:",popup "Square;Hann;Parzen;Welch;Hamming;"
"BlackmanHarris3;KaiserBessel"
;
PauseUpdate; silent 1
variable npsd= 2^(7+seglen) | number of points in group (resultant psd wave len= npsd/2+1)
variable psdOffset= npsd/2 | offset each group by this amount
variable psdFirst=0 | start of current group
variable nsrc= numpnts($w)
variable nsegs,winNorm | count of number of segements and window normalization factor
string destw=w+"_psd",srctmp=w+"_tmp"
string winw=w+"_psdWin" | window goes here
if( npsd > nsrc/2 )
Abort "psd: source wave should be MUCH longer than the segment length"
endif
make/o/n=(npsd/2+1) $destw
make/o/n=(npsd) $srctmp,$winw; $winw= 1
if( window==1 )
winNorm= 1
else
if( window==2 )
Hanning $winw;winNorm=0.372 | winNorm is avg squared value
else
if( window==3 )
winNorm= Parzen($winw)
else
if( window==4 )
winNorm= Welch($winw)
else
if( window==5 )
winNorm= Hamming($winw)
else
if( window==6 )
winNorm= BlackmanHarris3($winw)
else
if( window==7 )
winNorm= KaiserBessel($winw)
else
Abort "unknown window index"
endif
endif
endif
endif
endif
endif
endif | (kinda makes you wish we had elseif or switch constructs, huh?)
Duplicate/O/R=[0,npsd-1] $w $srctmp; $srctmp *= $winw; fft $srctmp
CopyScales/P $srctmp, $destw
$destw= magsqr($srctmp)
psdFirst= psdOffset
nsegs=1
do
Duplicate/O/R=[psdFirst,psdFirst+npsd-1] $w $srctmp; $srctmp *= $winw
fft $srctmp; $destw += magsqr($srctmp); psdFirst += psdOffset; nsegs+=1
while( psdFirst+npsd < nsrc )
winNorm= 2/(winNorm*nsegs*npsd^2); $destw *= winNorm
$destw[0] /= 2
KillWaves $srctmp,$winw
BringDestFront(destw)
if( numpnts($destw) <= 129 )
Modify mode($destw)=4,marker($destw)=19,msize($destw)=1
else
Modify mode($destw)=0
endif
end